﻿using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Serialization;
using CrawlerCore.XmlData;
using CrawlerCore.MinPrice;
using CrawlerCore.Helper;

namespace CrawlerCore
{
    public class VietJetAir
    {
        private string getPostdata(SearchInputService inputSearchJetstar)
        {
            StringBuilder postdata = new StringBuilder("");
            if (inputSearchJetstar.IsRoundTrip)
            {
                postdata.Append("chkRoundTrip=on");
            }
            else
            {
                postdata.Append("chkRoundTrip=");
            }
            postdata.Append("&lstOrigAP=" + inputSearchJetstar.DepartureCode);
            postdata.Append("&lstDestAp=" + inputSearchJetstar.ArrivalCode);
            postdata.Append("&dlstDepDate_Day=" + inputSearchJetstar.DepartTime.Day);
            postdata.Append("&dlstDepDate_Month=" + inputSearchJetstar.DepartTime.Year + "%2F" + inputSearchJetstar.DepartTime.Month);
            postdata.Append("&dlstRetDate_Day=" + inputSearchJetstar.ReturnTime.Day);
            postdata.Append("&dlstRetDate_Month=" + inputSearchJetstar.ReturnTime.Year + "%2F" + inputSearchJetstar.ReturnTime.Month);
            postdata.Append("&lstDepDateRange=0");
            postdata.Append("&lstRetDateRange=0");
            postdata.Append("&txtNumAdults=" + inputSearchJetstar.Adults);
            postdata.Append("&txtNumChildren=" + inputSearchJetstar.Children);
            postdata.Append("&txtNumInfants=" + inputSearchJetstar.Inf);
            postdata.Append("&lstLvlService=1");
            postdata.Append("&lstResCurrency=VND");
            postdata.Append("&lstCurrency=VND");
            postdata.Append("&blnFares=" + inputSearchJetstar.Infare);
            postdata.Append("&txtPromoCode=");
            return postdata.ToString();
        }
        private string getPostdata2(SearchInputService inputSearchJetstar)
        {
            string viewState = "%2FwEPDwULLTE1MzQ1MjI3MzAPZBYCZg9kFg4CCA8QZGQWAGQCCQ8QZGQWAGQCCw8QZGQWAGQCDQ8QZGQWAGQCEQ8QZGQWAGQCEg8QZGQWAGQCEw8QZGQWAGRkDuhQN17CT5ZIydlFFSt%2BWc8NsCA%3D";
            StringBuilder postdata = new StringBuilder("");
            postdata.Append("__VIEWSTATE=" + viewState);
            postdata.Append("&" + getPostdata(inputSearchJetstar));
            postdata.Append("&SesID=");
            postdata.Append("&DebugID=71");
            return postdata.ToString();
        }
        public Root CreateXmlDocument(SearchInputService input)
        {
            try
            {
                CrawlerHelper helper = new CrawlerHelper();
                Root root = new Root();
                root.Departure = input.DepartureCode;
                root.Arrival = input.ArrivalCode;
                CookieCollection cookieCollection = helper.getCookieCollection("https://ameliaweb5.intelisys.ca/VietJet/ameliapost.aspx?lang=vi", "POST", getPostdata(input));
                HtmlDocument htmld = helper.getDocument("https://ameliaweb5.intelisys.ca/VietJet/ameliapost.aspx?lang=vi", "POST", getPostdata2(input), cookieCollection);
                root.outBound = new OutInBound();
                root.inBound = new OutInBound();
                root.AirLine = AirLineName.vietJetAir;
                HtmlNodeCollection collection;
                try
                {
                    collection = htmld.DocumentNode.SelectNodes("//div[@id='toDepDiv']/div[@id='travOpsMain']/table[1]/tr[7]/td/table[1]/tr");
                    root.outBound.Items = getitems(input.DepartTime,input, collection);
                }
                catch { }
                //chieu ve
                if (input.IsRoundTrip)
                {
                    collection = htmld.DocumentNode.SelectNodes("//div[@id='toRetDiv']/div[@id='travOpsMain']/table[1]/tr[7]/td/table[1]/tr");
                    root.inBound.Items = getitems(input.ReturnTime,input, collection);
                }
                return root;
            }
            catch
            {
                return null;
            }
        }

        private List<Item> getitems(DateTime datetime,SearchInputService input, HtmlNodeCollection collection)
        {
            List<Item> items = new List<Item>();
            if (collection == null)
                return items;
            foreach (HtmlNode node in collection)
            {
                HtmlNodeCollection collectionRecord = node.SelectNodes("td");
                try
                {
                    Item item = new Item();
                    HtmlNode node1;
                    HtmlNodeCollection colectionTimeNo = collectionRecord.ElementAt(0).SelectNodes("table/tr[1]/td");
                    node1 = colectionTimeNo.ElementAt(0);
                    string departureTime = node1.InnerHtml.Replace("&nbsp;", " ").Replace("<br>", " ").Split(' ')[0];
                    item.departureTime = DateTimeHelper.getDate(datetime, departureTime);
                    node1 = colectionTimeNo.ElementAt(1);
                    string arriveTime = node1.InnerHtml.Replace("&nbsp;", " ").Replace("<br>", " ").Split(' ')[0];
                    item.arriveTime = DateTimeHelper.getDate(datetime, arriveTime);
                    //kiem tra lai thoi gian den
                    DateTime timeTemp = DateTime.Parse(item.arriveTime);
                    if (timeTemp.Hour < DateTime.Parse(item.departureTime).Hour)
                    {
                        item.arriveTime = timeTemp.AddDays(1).ToString();
                    }

                    node1 = colectionTimeNo.ElementAt(2);
                    item.flightNo = node1.SelectSingleNode("span").InnerText;
                    HtmlNodeCollection colectionPrice = collectionRecord.ElementAt(1).SelectNodes("table/tr[1]/td");
                    Price p;
                    item.price = new List<Price>();
                    try
                    {
                        p = new Price
                        {
                            name = "Promo",
                            price = WebUtility.HtmlDecode(colectionPrice.ElementAt(0).InnerText.Trim()).Replace(",", ""),
                            taxPrice = colectionPrice.ElementAt(0).SelectSingleNode("input[@id='charges']").Attributes["value"].Value.Replace(",", "")
                        };
                        decimal.Parse(p.price);
                        item.price.Add(p);
                    }
                    catch { }

                    try
                    {
                        p = new Price
                        {
                            name = "Eco",
                            price = WebUtility.HtmlDecode(colectionPrice.ElementAt(1).InnerText.Trim()).Replace(",", ""),
                            taxPrice = colectionPrice.ElementAt(1).SelectSingleNode("input[@id='charges']").Attributes["value"].Value.Replace(",", "")
                        };
                        decimal.Parse(p.price);
                        item.price.Add(p);
                    }
                    catch { }

                    try
                    {
                        p = new Price
                        {
                            name = "Deluxe",
                            price = WebUtility.HtmlDecode(colectionPrice.ElementAt(2).InnerText.Trim()).Replace(",", ""),
                            taxPrice = colectionPrice.ElementAt(2).SelectSingleNode("input[@id='charges']").Attributes["value"].Value.Replace(",", "")
                        };
                        decimal.Parse(p.price);
                        item.price.Add(p);
                    }
                    catch { }
                    if (item.price != null && item.price.Count > 0)
                        items.Add(item);
                }
                catch { }
            }
            return items;
        }

        public RootMinPrice GetPriceInFare(SearchInputService input)
        {
            try
            {
                CrawlerHelper helper = new CrawlerHelper();
                CookieCollection cookieCollection = helper.getCookieCollection("https://ameliaweb5.intelisys.ca/VietJet/ameliapost.aspx?lang=vi", "POST", getPostdata(input));
                HtmlDocument htmld = helper.getDocument("https://ameliaweb5.intelisys.ca/VietJet/ameliapost.aspx?lang=vi", "POST", getPostdata2(input), cookieCollection);
                //File.WriteAllText("D:",htmld.DocumentNode.InnerHtml);
                HtmlNode nodeTemp = htmld.DocumentNode.SelectSingleNode("//div[@id='vvDepDiv']/table");
                RootMinPrice root = new RootMinPrice();
                root.departurePrices = new OutInBoundPrices();
                root.departurePrices.prices = GetListPrices(nodeTemp, input.DepartTime);
                if (input.IsRoundTrip)
                {
                    root.arrivePrices = new OutInBoundPrices();
                    nodeTemp = htmld.DocumentNode.SelectSingleNode("//div[@id='vvRetDiv']/table");
                    root.arrivePrices.prices = GetListPrices(nodeTemp, input.ReturnTime);
                }
                return root;
            }
            catch
            {
                return null;
            }
        }

        private List<MinPriceDetail> GetListPrices(HtmlNode nodeTemp, DateTime dateTime)
        {
            if (nodeTemp == null)
            {
                return null;
            }
            List<MinPriceDetail> l = new List<MinPriceDetail>();
            HtmlNodeCollection nodesTds = nodeTemp.SelectNodes(".//td[contains(@class,'fareClass')]");
            foreach (HtmlNode node1 in nodesTds)
            {
                try
                {
                    MinPriceDetail mdt = new MinPriceDetail();
                    mdt.Price = node1.SelectSingleNode("div/p").InnerText.Replace(",", "");
                    node1.SelectSingleNode("div").RemoveChild(node1.SelectSingleNode("div/p"));
                    string day = node1.SelectSingleNode("div").InnerText;
                    mdt.Date = new DateTime(dateTime.Year, dateTime.Month, int.Parse(day));
                    l.Add(mdt);
                }
                catch { }
            }
            return l;
        }
    }
}